package cn.yto.print.system;

import cn.yto.print.AssistantApplication;
import cn.yto.print.config.ThreadPoolManager;
import cn.yto.print.constants.AssistantConstants;
import javafx.application.Platform;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;


@Slf4j
@Component
public class ActivationSocketServer {

    @Value("${app.socket.port}")
    private int socketPort;

    private ServerSocket serverSocket;

    @PostConstruct
    public void startServer() {
        // 初始化服务端Socket，并启动异步监听
        initializeServerSocket().ifPresent(socket -> {
            serverSocket = socket;
            CompletableFuture.runAsync(this::listenForClients, ThreadPoolManager.getExecutorService());
            log.info("Socket server started on port: {}", socketPort);
        });
    }

    private Optional<ServerSocket> initializeServerSocket() {
        try {
            return Optional.of(new ServerSocket(socketPort));
        } catch (IOException e) {
            log.error("Error while starting the socket server: ", e);
            return Optional.empty();
        }
    }

    /**
     * 持续监听客户端连接请求
     */
    private void listenForClients() {
        while (!serverSocket.isClosed()) {
            acceptClient().ifPresent(this::handleClientSafely);
        }
    }

    private Optional<Socket> acceptClient() {
        try {
            return Optional.of(serverSocket.accept());
        } catch (IOException e) {
            log.error("Error accepting client connection: ", e);
            return Optional.empty();
        }
    }

    private void handleClientSafely(Socket clientSocket) {
        try (Socket socket = clientSocket;
             DataInputStream in = new DataInputStream(socket.getInputStream())) {
            readCommand(in).ifPresent(this::dispatchCommand);
        } catch (IOException e) {
            log.error("Error while handling client connection: ", e);
        }
    }

    /**
     * 从输入流读取客户端发送的命令。
     */
    private Optional<String> readCommand(DataInputStream in) {
        try {
            return Optional.ofNullable(in.readUTF());
        } catch (IOException e) {
            log.error("Error reading command from client: ", e);
            return Optional.empty();
        }
    }

    private void dispatchCommand(String command) {
        log.info("Socket server received command: {}", command);
        if (AssistantConstants.SHOW_COMMAND.equals(command)) {
            activateMainWindow();
        }
    }

    private void activateMainWindow() {
        Runnable showWindow = () -> {
            // 取消最小化
            Stage stage = AssistantApplication.getStage();
            if (stage.isIconified()) {
                stage.setIconified(false);
            }
            // 显示窗口
            stage.show();
            stage.toFront();
        };
        Platform.runLater(showWindow);
    }

}
